package com.fastdfs.service;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Set;


import com.fastdfs.domain.MataData;
import com.fastdfs.exception.FdfsIOException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.Validate;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.fastdfs.domain.StorageNode;
import com.fastdfs.domain.StorePath;
import com.fastdfs.proto.storage.StorageSetMetadataCommand;
import com.fastdfs.proto.storage.StorageUploadFileCommand;
import com.fastdfs.proto.storage.enums.StorageMetdataSetType;


/**
 * 面向应用的接口实现
 * 
 * @author tobato
 *
 */
@Component
//@Scope("prototype")
public class DefaultFastFileStorageClient extends DefaultGenerateStorageClient implements FastFileStorageClient {

    /** 支持的图片类型 */
    private static final String[] SUPPORT_IMAGE_TYPE = { "JPG", "JPEG", "PNG", "GIF", "BMP", "WBMP" };
    private static final List<String> SUPPORT_IMAGE_LIST = Arrays.asList(SUPPORT_IMAGE_TYPE);
    /** 缩略图生成配置 */


    /**
     * 上传文件
     */
    @Override
    public StorePath uploadFile(InputStream inputStream, long fileSize, String fileExtName, Set<MataData> metaDataSet) {
        Validate.notNull(inputStream, "上传文件流不能为空");
        //Validate.notBlank(fileExtName, "文件扩展名不能为空");
        if(fileExtName==null)
            fileExtName="123";
        StorageNode client = trackerClient.getStoreStorage();
        return uploadFileAndMataData(client, inputStream, fileSize, fileExtName, metaDataSet);
    }

//    /**
//     * 上传图片并且生成缩略图
//     */
//    @Override
//    public StorePath uploadImageAndCrtThumbImage(InputStream inputStream, long fileSize, String fileExtName,
//            Set<MataData> metaDataSet) {
//        Validate.notNull(inputStream, "上传文件流不能为空");
//        Validate.notBlank(fileExtName, "文件扩展名不能为空");
//        // 检查是否能处理此类图片
//        if (!isSupportImage(fileExtName)) {
//            throw new FdfsUnsupportImageTypeException("不支持的图片格式" + fileExtName);
//        }
//        StorageNode client = trackerClient.getStoreStorage();
//        byte[] bytes = inputStreamToByte(inputStream);
//
//        // 上传文件和mataData
//        StorePath path = uploadFileAndMataData(client, new ByteArrayInputStream(bytes), fileSize, fileExtName,
//                metaDataSet);
//        // 上传缩略图
//     //   uploadThumbImage(client, new ByteArrayInputStream(bytes), path.getPath(), fileExtName);
//        bytes = null;
//        return path;
//    }

    /**
     * 获取byte流
     * 
     * @param inputStream
     * @return
     */
    private byte[] inputStreamToByte(InputStream inputStream) {
        try {
            return IOUtils.toByteArray(inputStream);
        } catch (IOException e) {
            LOGGER.error("image inputStream to byte error", e);
            throw new FdfsIOException("upload ThumbImage error", e.getCause());
        }
    }

    /**
     * 检查是否有MataData
     * 
     * @param metaDataSet
     * @return
     */
    private boolean hasMataData(Set<MataData> metaDataSet) {
        return null != metaDataSet && !metaDataSet.isEmpty();
    }

    /**
     * 是否是支持的图片文件
     * 
     * @param fileExtName
     * @return
     */
    private boolean isSupportImage(String fileExtName) {
        return SUPPORT_IMAGE_LIST.contains(fileExtName.toUpperCase());
    }

    /**
     * 上传文件和元数据
     * 
     * @param client
     * @param inputStream
     * @param fileSize
     * @param fileExtName
     * @param metaDataSet
     * @return
     */
    private StorePath uploadFileAndMataData(StorageNode client, InputStream inputStream, long fileSize,
                                            String fileExtName, Set<MataData> metaDataSet) {
        // 上传文件
        StorageUploadFileCommand command = new StorageUploadFileCommand(client.getStoreIndex(), inputStream,
                fileExtName, fileSize, false);
        StorePath path = connectionManager.executeFdfsCmd(client.getInetSocketAddress(), command);
        // 上传matadata
        if (hasMataData(metaDataSet)) {
            StorageSetMetadataCommand setMDCommand = new StorageSetMetadataCommand(path.getGroup(), path.getPath(),
                    metaDataSet, StorageMetdataSetType.STORAGE_SET_METADATA_FLAG_OVERWRITE);
            connectionManager.executeFdfsCmd(client.getInetSocketAddress(), setMDCommand);
        }
        return path;
    }

    /**
     * 删除文件
     */
    @Override
    public void deleteFile(String filePath) {
        StorePath storePath = StorePath.praseFromUrl(filePath);
        super.deleteFile(storePath.getGroup(), storePath.getPath());
    }

}
